var phongKFEffectVertexShaderStr = "\
attribute vec3 inPositionk1;\
attribute vec3 inPositionk2;\
attribute vec3 inPositionk3;\
attribute vec3 inPositionk4;\
attribute vec3 inPositionk5;\
attribute vec3 inNormalk1;\
attribute vec3 inNormalk2;\
attribute vec3 inNormalk3;\
attribute vec3 inNormalk4;\
attribute vec3 inNormalk5;\
attribute vec2 inTexCoord0k1;\
attribute vec2 inTexCoord0k2;\
attribute vec2 inTexCoord0k3;\
attribute vec2 inTexCoord0k4;\
attribute vec2 inTexCoord0k5;\
uniform float properties[16];\
uniform mat4 normalMat;\
uniform mat4 modelMat;\
uniform mat4 viewMat;\
uniform mat4 projectionMat;\
uniform mat4 modelViewProjectionMat;\
uniform mat4 shadowMat;\
uniform vec4 viewPosition;\
varying vec3 outNormalInWorld;\
varying vec3 outViewVector;\
varying vec2 outTexCoord0;\
varying vec4 shadowCoord;\
void main(void)\
{\
  float time = properties[4];\
  int key;\
  if(time<=properties[6])\
    key=1;\
  else if(time<=properties[7])\
    key=2;\
  else if(time<=properties[8])\
    key=3;\
  else if(time<=properties[9])\
    key=4;\
  else\
    key=5;\
  vec3 current_pos = inPositionk1;\
  vec2 current_tex = inTexCoord0k1;\
  vec3 current_nor = inNormalk1;\
  float w;\
  if(key==1)\
  {\
    w = (time-properties[5])/(properties[6]-properties[5]);\
    if(properties[1]>1.)\
    current_pos = (1-w)*inPositionk1+w*inPositionk2;\
  if(properties[2]>1.)\
    current_tex = (1-w)*inTexCoord0k1+w*inTexCoord0k2;\
  if(properties[3]>1.)\
    current_nor = (1-w)*inNormalk1+w*inNormalk2;\
  }\
  if(key==2)\
  {\
    w = (time-properties[6])/(properties[7]-properties[6]);\
    if(properties[1]>1)\
    current_pos = (1-w)*inPositionk2+w*inPositionk3;\
  if(properties[2]>1.)\
    current_tex = (1-w)*inTexCoord0k2+w*inTexCoord0k3;\
  if(properties[3]>1)\
    current_nor = (1-w)*inNormalk2+w*inNormalk3;\
  }\
  if(key==3)\
  {\
    w = (time-properties[7])/(properties[8]-properties[7]);\
    if(properties[1]>1)\
    current_pos = (1-w)*inPositionk3+w*inPositionk4;\
  if(properties[2]>1.)\
    current_tex = (1-w)*inTexCoord0k3+w*inTexCoord0k4;\
  if(properties[3]>1)\
    current_nor = (1-w)*inNormalk3+w*inNormalk4;\
  }\
  if(key==4)\
  {\
    w = (time-properties[8])/(properties[9]-properties[8]);\
    if(properties[1]>1)\
    current_pos = (1-w)*inPositionk4+w*inPositionk5;\
  if(properties[2]>1.)\
    current_tex = (1-w)*inTexCoord0k4+w*inTexCoord0k5;\
  if(properties[3]>1)\
    current_nor = (1-w)*inNormalk4+w*inNormalk5;\
  }\
  if(key==5)\
  {\
    w = (time-properties[9])/(properties[10]-properties[9]);\
    if(properties[1]>1)\
    current_pos = (1-w)*inPositionk5+w*inPositionk1;\
  if(properties[2]>1.)\
    current_tex = (1-w)*inTexCoord0k5+w*inTexCoord0k1;\
  if(properties[3]>1)\
    current_nor = (1-w)*inNormalk5+w*inNormalk1;\
  }\
  gl_Position = modelViewProjectionMat*vec4(current_pos, 1.0);\
  shadowCoord = shadowMat*modelMat*vec4(current_pos,1.0);\
  outNormalInWorld = (normalMat*vec4(current_nor,1.0)).xyz;\
  vec4 posInWorld = modelMat*vec4(current_pos, 1.0);\
  outViewVector = viewPosition.xyz - vec3(posInWorld);\
  outTexCoord0 = inTexCoord0k1;\
}\
";
var phongKFEffectFragmentShaderStr = phongEffectFragmentShaderStr;
function gewPhongKFEffect(game)
{
  // General properties
  this.game = game;
  this.gl = game.gl;
  var gl = game.gl;
  this.name = "PhongKFEffect";
  this.scene3d = null;//Current scene3d that using this effect 
  this.materialList = {};
  this.currentPass = null;
  // Shader properties
  this.vs = createVertexShader(gl, phongKFEffectVertexShaderStr);
  this.fs = createFragmentShader(gl, phongKFEffectFragmentShaderStr);
  var program = gl.createProgram();
  gl.attachShader(program, this.vs);
  gl.attachShader(program, this.fs);
  gl.linkProgram(program);
  checkProgramLinkStatus(gl, program);
  this.program = program;
  // Shader param id
  this.inPosition = [];
  this.inNormal = [];
  this.inTexCoord0 = [];
  this.inPosition[0] = gl.getAttribLocation(program, "inPositionk1");
  this.inPosition[1] = gl.getAttribLocation(program, "inPositionk2");
  this.inPosition[2] = gl.getAttribLocation(program, "inPositionk3");
  this.inPosition[3] = gl.getAttribLocation(program, "inPositionk4");
  this.inPosition[4] = gl.getAttribLocation(program, "inPositionk5");
  this.inNormal[0] = gl.getAttribLocation(program, "inNormalk1");
  this.inNormal[1] = gl.getAttribLocation(program, "inNormalk2");
  this.inNormal[2] = gl.getAttribLocation(program, "inNormalk3");
  this.inNormal[3] = gl.getAttribLocation(program, "inNormalk4");
  this.inNormal[4] = gl.getAttribLocation(program, "inNormalk5");
  this.inTexCoord0[0] = gl.getAttribLocation(program, "inTexCoord0k1");
  this.inTexCoord0[1] = gl.getAttribLocation(program, "inTexCoord0k2");
  this.inTexCoord0[2] = gl.getAttribLocation(program, "inTexCoord0k3");
  this.inTexCoord0[3] = gl.getAttribLocation(program, "inTexCoord0k4");
  this.inTexCoord0[4] = gl.getAttribLocation(program, "inTexCoord0k5");
  this.properties = gl.getUniformLocation(program, "properties");
  this.modelMat = gl.getUniformLocation(program, "modelMat");
  this.viewMat = gl.getUniformLocation(program, "viewMat");
  this.projectionMat = gl.getUniformLocation(program, "projectionMat");
  this.normalMat = gl.getUniformLocation(program, "normalMat");
  this.modelViewProjectionMat = gl.getUniformLocation(program, "modelViewProjectionMat");
  this.viewPosition = gl.getUniformLocation(program, "viewPosition");
  this.texture0 = gl.getUniformLocation(program, "texture0");
  this.shadowMap = gl.getUniformLocation(program, "shadowMap");
  this.lightData = gl.getUniformLocation(program, "lightData");
  this.shadowMat = gl.getUniformLocation(program, "shadowMat");
  this.ambient = gl.getUniformLocation(program, "ambient");
  this.specular = gl.getUniformLocation(program, "specular");
  //this.shininess = gl.getUniformLocation(program, "shininess");
  this.diffuse = gl.getUniformLocation(program, "diffuse");
}

gewPhongKFEffect.prototype.render = function(scene3d)
{
  var gl = this.gl;
  this.scene3d = scene3d;
  // push GL state
  // set GL state
  gl.useProgram(this.program);
  gl.enableVertexAttribArray(this.inPosition[0]);
  gl.enableVertexAttribArray(this.inPosition[1]);
  gl.enableVertexAttribArray(this.inPosition[2]);
  gl.enableVertexAttribArray(this.inPosition[3]);
  gl.enableVertexAttribArray(this.inPosition[4]);
  gl.enableVertexAttribArray(this.inNormal[0]);
  gl.enableVertexAttribArray(this.inNormal[1]);
  gl.enableVertexAttribArray(this.inNormal[2]);
  gl.enableVertexAttribArray(this.inNormal[3]);
  gl.enableVertexAttribArray(this.inNormal[4]);
  gl.enableVertexAttribArray(this.inTexCoord0[0]);
  gl.enableVertexAttribArray(this.inTexCoord0[1]);
  gl.enableVertexAttribArray(this.inTexCoord0[2]);
  gl.enableVertexAttribArray(this.inTexCoord0[3]);
  gl.enableVertexAttribArray(this.inTexCoord0[4]);
  gl.enable(gl.DEPTH_TEST);
  gl.enable(gl.CULL_FACE);
  gl.uniform3fv(this.lightData, scene3d.mainLight.lightData);
  var light = scene3d.mainLight;
  var shadowMat = GEW_SHADOW_BIAS_MAT.mul(light.projectionMat).mul(light.viewMat);
  gl.uniformMatrix4fv(this.shadowMat, false, shadowMat.data);
  // render pass 0 with all material
  this.currentPass = 0;
  var materialList = this.materialList;
  var listLen = materialList.length;
  for (var i in materialList) 
  {
    materialList[i].render();
  }
  //
  gl.currentPass = null;
  // pop GL state  
  gl.disable(gl.DEPTH_TEST);
  gl.disable(gl.CULL_FACE);
  gl.disableVertexAttribArray(this.inPosition[0]);
  gl.disableVertexAttribArray(this.inPosition[1]);
  gl.disableVertexAttribArray(this.inPosition[2]);
  gl.disableVertexAttribArray(this.inPosition[3]);
  gl.disableVertexAttribArray(this.inPosition[4]);
  gl.disableVertexAttribArray(this.inNormal[0]);
  gl.disableVertexAttribArray(this.inNormal[1]);
  gl.disableVertexAttribArray(this.inNormal[2]);
  gl.disableVertexAttribArray(this.inNormal[3]);
  gl.disableVertexAttribArray(this.inNormal[4]);
  gl.disableVertexAttribArray(this.inTexCoord0[0]);
  gl.disableVertexAttribArray(this.inTexCoord0[1]);
  gl.disableVertexAttribArray(this.inTexCoord0[2]);
  gl.disableVertexAttribArray(this.inTexCoord0[3]);
  gl.disableVertexAttribArray(this.inTexCoord0[4]);
}
